package hyl.core.fun;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjuster;
import java.util.Date;

/**
 * 是MyDate 的补充函数 , 未完成??? 还需要加入时区变化处理函数
 */
public class MyDate2 {
	/**
	 * 将LocalDate 转换成 Date atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
	 */
	public static Date LocalDate2Date(LocalDate localDate) {
		return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
	}

	/**
	 * 将LocalDateTime 转换成 Date atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
	 */
	public static Date LocalDateTime2Date(LocalDateTime localDateTime) {
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
	}

	/**
	 * 将 Date 转换成LocalDate atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
	 */
	public static LocalDate Date2LocalDate(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
	}

	/**
	 * 将 Date 转换成LocalDateTime atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
	 */
	public static LocalDateTime Date2LocalDateTime(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	public static LocalTime Date2LocalTime(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalTime();
	}

	/**
	 * 将localDate 按照一定的格式转换成String
	 * 
	 * @param localDate
	 * @param pattern
	 * @return
	 */
	public static String localDateFormat(LocalDate localDate, String pattern) {
		return localDate.format(DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将localDateTime 按照一定的格式转换成String
	 * 
	 * @param localDateTime
	 * @param pattern
	 * @return
	 */
	public static String localDateTimeFormat(LocalDateTime localDateTime, String pattern) {
		return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将String 按照pattern 转换成LocalDate
	 * 
	 * @param time
	 * @param pattern
	 * @return
	 */
	public static LocalDate localDateParse(String time, String pattern) {
		return LocalDate.parse(time, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将String 按照pattern 转换成LocalDateTime
	 * 
	 * @param time
	 * @param pattern
	 * @return
	 */
	public static LocalDateTime localDateTimeParse(String time, String pattern) {
		return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 计算两个LocalDate 之间的Period<BR>
	 * Period 类表示一段时间的年、月、日，<BR>
	 * 使用between()方法获取两个日期之间的差作为Period 对象返回：
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static Period getPeriod(LocalDate time1, LocalDate time2) {
		return Period.between(time1, time2);
	}

	/**
	 * 计算两个Date 之间的Period<BR>
	 * Period 类表示一段时间的年、月、日，<BR>
	 * 使用between()方法获取两个日期之间的差作为Period 对象返回：
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static Period getPeriod(Date date1, Date date2) {
		return getPeriod(Date2LocalDate(date1), Date2LocalDate(date2));
	}

	/**
	 * 计算两个Date之间的 Duration <BR>
	 * Duration类表示秒或纳秒时间间隔，适合处理较短的时间，需要更高的精确性。<BR>
	 * 我们能使用between()方法比较两个瞬间的差：<BR>
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static Long getDurationDate(Date time1, Date time2) {
		return getDuration(Date2LocalDateTime(time1), Date2LocalDateTime(time2)).toMillis();
	}

	/**
	 * 计算两个Date之间的 Duration <BR>
	 * Duration类表示秒或纳秒时间间隔，适合处理较短的时间，需要更高的精确性。<BR>
	 * 我们能使用between()方法比较两个瞬间的差：<BR>
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static Duration getDuration(LocalDateTime time1, LocalDateTime time2) {
		return Duration.between(time1, time2);
	}

	/**
	 * 计算两个Date之间的 Duration <BR>
	 * Duration类表示秒或纳秒时间间隔，适合处理较短的时间，需要更高的精确性。<BR>
	 * 我们能使用between()方法比较两个瞬间的差：<BR>
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static Duration getDuration(LocalTime time1, LocalTime time2) {
		return Duration.between(time1, time2);
	}

	/**
	 * LocalDate date = LocalDate.parse( String Dt);<br>
	 * return date.with(TemporalAdjusters.firstDayOfMonth());
	 * 
	 * <br>
	 * TemporalAdjusters.firstDayOfMonth(); //获取单月第一天 <br>
	 * TemporalAdjusters.lastDayOfMonth();//获取月最后一天 <br>
	 * TemporalAdjusters.firstDayOfNextMonth();//获取下个月第一天 <br>
	 * TemporalAdjusters.firstDayOfNextYear();//获取明年第一天 <br>
	 * TemporalAdjusters.firstDayOfYear();//获取今年第一天 <br>
	 * TemporalAdjusters.lastDayOfYear();//获取今年最后一天 <br>
	 * TemporalAdjusters.next(DayOfWeek.MONDAY); //获取下一个周一 <br>
	 * TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY);//获取下一个星期几,如果等于今天返回今天 <br>
	 * TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY);//月的最后一个星期几 <br>
	 * TemporalAdjusters.previous(DayOfWeek.MONDAY);//上一个星期几 <br>
	 * TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY);//上一个星期几,如果等于今天返回今天 <br>
	 * TemporalAdjusters.dayOfWeekInMonth(第几个, 星期几) //返回从计算日开始 第几个星级几 是几号
	 * 
	 * @param da
	 * @param adjuster
	 * @return
	 */
	public static LocalDate with(Date da, TemporalAdjuster adjuster) {
		return Date2LocalDate(da).with(adjuster);
	}

	public static DateTimeFormatter YYYYMMDD = DateTimeFormatter.BASIC_ISO_DATE;
	public static DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ISO_DATE;
}
